<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Vue-列表|list 渲染</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>

<body>
    <!--
        基于v-for 进行列表渲染
    -->
    <div>
        <ul id="app-1">
            <li v-for="item in items">
                {{ item.msg }}
            </li>
        </ul>
    </div>
    <!--
        获取v-for 循环下标
    -->
    <div>
        <ul id="app-2">
            <li v-for="(item,index) in items">
                {{ parentMsg }} - {{ index }} - {{ item.msg }}
            </li>
        </ul>
    </div>

    <!-- 用 of 替代 in-->
    <div>
        <ul id="app-3">
            <li v-for="item of items">
                {{ item.msg }}
            </li>
        </ul>
    </div>

    <!-- v-for + template 标签 -->
    <ul id="app-4">
        <template v-for="item in items">
            <li>{{ item.msg }}</li>
            <li class="divider"></li>
        </template>
    </ul>

    <!--
        对象迭代
    -->
    <div id="app-5">
        <ul class="demo1">
            <li v-for="value in object">
                {{ value }}
            </li>
        </ul>
        <ul class="demo2">
            <li v-for="(value, key) in object">
                {{ key }} : {{ value }}
            </li>
        </ul>
        <ul class="demo3">
            <li v-for="(value, key,index) in object">
                {{ index }} - {{ key }} : {{ value }}
            </li>
        </ul>

    </div>

    <!-- 整数遍历 -->
    <div id="app-6">
        <span v-for="n in 10">{{ n }}</span>
    </div>

    <!-- 自定义组件遍历 ，todo list 实现-->
    <div id="todo-list-demo">
        <input v-model="newTodoItems" v-on:keyup.enter="addNewTodo" placeholder="添加代办事项">
        <p>代办事项列表:</p>
        <ul>
            <!-- 绑定自定义组件 todo=item-->
            <li is="todo-item" v-for="(todo,index) in todos" v-bind:title="todo" v-on:remove="todos.splice(index,1)"></li>
        </ul>

    </div>

    <!-- v-for 和 v-if的关系 在同一个节点中，v-for 优先级更高，也就是循环总会执行，
    不过v-if控制其绑定 -->
    <ul id="app-7">
        <li v-for="todo in todos" v-if="!todo.isComplete">
            {{todo.text}}
        </li>
    </ul>

    <!--
        Vue 的key机制。
        在面临重排，需要让VUE追踪到需要重新渲染的组件，通常这个时候需要用一个key 进行标注
        通常这种情况下面结合v-for是一个不错的做法，使用:key绑定组件key

        <div v-for="item in items" :key="item.id">

        </div>
    -->

    <!--
        通过vue 的MVVM设计，通过调用特定的数组操作函数改变数组内容时，vue可以捕捉数据变化
        ，将改变渲染到界面上面来。具体的方法有：
        push()
        pop()
        shift()
        unshift()
        splice()
        sort()
        reverse()

        当然也有些方法，不会改变原有数组的内容和大小，但是是会返回一个新数组。如果也需要更新
        界面，可以将旧数组指向新数组

        example1.items = example1.items.filter(function (item) {
            return item.message.match(/Foo/)
        })


        由于js本身的限制，以下的三种操作vue无法监听到变化

        1.直接设置值(新增/更新)
        vm.items[10] = 'xxxx'

        比如我直接追加一个元素，这样是监听不到变化的：
        vm.items[vm.items.length]='新内容'

        2.修改数组长度
        vm.items.length=100
        
        针对上面的需求，有如下的解决方案：
        问题1：

        Vue.set(app.items,10,'要设置的新值') // 基于vue本身的方法

        app.items.splice(10,1,'要设置的新值') // 基于array的splice方法

        问题2：

        app.items.splice(新长度) // 也是通过splice实现



    -->

    <!-- 在列表里面，我们经常需要做一些过滤操作,这种情况下面往往需要重置搜索条件，
        也就意味着不能更改原来的数据。
        这个问题可以基于计算属性computed 和 调用方法实现，下面是例子
     -->
    <div id="app-filter">
        <p>基于计算属性:computed</p>
        <ul>
            <li v-for="n in evenNumbers">
                数据:{{ n}}
            </li>
        </ul>
        <p>基于方法:method</p>
        <ul>
            <li v-for="n in even(numbers)">
                数据:{{ n}}
            </li>
        </ul>
    </div>


</body>
<script>
    var app1 = new Vue({
        el: '#app-1',
        data: {
            items: [
                { msg: '《凤凰传奇》' },
                { msg: '《FIR》' },
            ]
        }
    })

    var app2 = new Vue({
        el: '#app-2',
        data: {
            parentMsg: '下标展示',
            items: [
                { msg: '《来去之间》' },
                { msg: '《今何在》' },
            ]
        }
    })

    var app3 = new Vue({
        el: '#app-3',
        data: {
            items: [
                { msg: 'QQ' },
                { msg: '微信' },
            ]
        }
    })

    var app4 = new Vue({
        el: '#app-4',
        data: {
            items: [
                { msg: 'Google' },
                { msg: 'Facebook' },
            ]
        }
    })

    var app5 = new Vue({
        el: '#app-5',
        data: {
            object: {
                FirstName: 'John',
                LastName: 'Doe',
                Age: 30
            }
        }
    })

    var app6 = new Vue({
        el: '#app-6',
        data: {

        }
    })

    // 自定义组件,这里将clink事件转换为remove方法
    Vue.component('todo-item', {
        template: '\
            <li>\
              {{ title }}\
              <button v-on:click="$emit(\'remove\')">X</button>\
            </li>\
        ',
        props: ['title']
    })

    var todoDemos = new Vue({
        el: '#todo-list-demo',
        data: {
            newTodoItems: '',
            todos: [
                '写JIRA报表的存储过程',
                '开站会',
                '学习Vue'
            ]
        },
        methods: {
            addNewTodo: function () {
                this.todos.push(this.newTodoItems)
                this.newTodoItems = ''
            }
        }
    })

    var app7 = new Vue({
        el:'#app-7',
        data:{
            todos:[
                {
                    isComplete:true,
                    text:'写代码'
                },
                 {
                    isComplete:false,
                    text:'吃午餐'
                },
                 {
                    isComplete:false,
                    text:'回家'
                },
            ]
        }
    })

    var appFilter = new Vue({
        el:'#app-filter',
        data:{
            numbers:[1,2,3,4,5,6,7]
        },
        computed:{
            evenNumbers:function(){
                return this.numbers.filter(function(number){
                    return number % 2 === 0
                })
            }
        },
        methods:{
            even:function(numbers){
                return numbers.filter(function(number){
                    return number % 2 === 0
                })
            }
        }
    })

</script>

</html>